import java.awt.Color;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Random;

import javax.swing.JOptionPane;


public class GameFunction 
{
	
	//holds the tiles
	static ArrayList<Tile> tiles = new ArrayList<Tile>();
	static ArrayList<Point> cords = new ArrayList<Point>();
	static ArrayList<Point> openCords = new ArrayList<Point>();
	//holds current GUI
	static GameScreen object;
	//holds current score
	private static int score;
	//holds current high score
	private static int high;
	//private int highScore;
	
	private static boolean checker = false;
	
	public static void countMethod(Tile tile)
	{
		score += tile.getNum();
		if (score > high)
				high = score;
		object.updateScore(score, high);
	}
	
	public static void moveMethod(String direction)
	{
		//Move blocks
		//call gen method
		
		
		switch(direction)
		{
			case"up":
			{
				//SORT THE MOTHERTRUCKING ARRAYLIST
				for(int i = 1; i < tiles.size(); i++)
				{
					Tile tempTile = tiles.get(i);
					
					int j;
					for(j = i - 1; j >= 0 && tempTile.getY() < tiles.get(j).getY(); j--)
					{
						tiles.set(j + 1, tiles.get(j));
					}
					
					tiles.set(j + 1, tempTile);
				}
					//check if can move, and if it can move, check if it can combine
					for(int i = 0; i < tiles.size(); i++)
					{
						boolean moveTile = true;
							//check if location above is valid part of grid
							if(tiles.get(i).getLocation().getAdjacentLocation(direction).getCol() < 4 && tiles.get(i).getLocation().getAdjacentLocation(direction).getCol() >= 0)
							{
								Location loc = tiles.get(i).getLocation().getAdjacentLocation(direction);
								//find the tile at the loc. If there is none, move the tile to that location
								for(int z = 0; z < tiles.size(); z++)
								{
									if(tiles.get(z).getLocation().equals(loc) == true)
									{
										//System.out.println("Stuck?");
										//check if nums are the same, then call combine
										//do not call combine or move in here, or it'll loop. Need to break out of here.
										if(tiles.get(z).getNum() == tiles.get(i).getNum())
										{
											combineTiles(tiles.get(i), tiles.get(z), direction);
										}
										moveTile = false;
									}
								}
								if(moveTile == true)
								{
									while(moveTile == true)
									{
										
										for(int l = 0; l < tiles.size(); l++)
										{
											if(tiles.get(l).getLocation().equals(loc))
											{
												moveTile = false;
											}
										}
										//make this if statement check loc instead of dis stuff
										if(loc.getCol() < 0 || loc.getCol() > 3)
										{
											moveTile = false;
										}
										if (moveTile == true)
										{
											System.out.println(tiles.get(i).getLocation().getCol());
											tiles.get(i).setLocation(loc);
											System.out.println(tiles.get(i).getLocation().getCol());
											loc = tiles.get(i).getLocation().getAdjacentLocation(direction);
										}
									}
								}
							}
						}
					
					break;
				}
			case"down":
			{
				//SORT THE MOTHERTRUCKING ARRAYLIST
				for(int i = 1; i < tiles.size(); i++)
				{
					Tile tempTile = tiles.get(i);
					
					int j;
					for(j = i - 1; j >= 0 && tempTile.getY() > tiles.get(j).getY(); j--)
					{
						tiles.set(j + 1, tiles.get(j));
					}
					
					tiles.set(j + 1, tempTile);
				}
				
				//check if can move, and if it can move, check if it can combine
				for(int i = 0; i < tiles.size(); i++)
				{
					boolean moveTile = true;
						
						//check if location above is valid part of grid
						if(tiles.get(i).getLocation().getAdjacentLocation(direction).getCol() < 4 && tiles.get(i).getLocation().getAdjacentLocation(direction).getCol() >= 0)
						{
							
							Location loc = tiles.get(i).getLocation().getAdjacentLocation(direction);
							//find the tile at the loc. If there is none, move the tile to that location
							for(int z = 0; z < tiles.size(); z++)
							{
								
								if(tiles.get(z).getLocation().equals(loc) == true)
								{
									//System.out.println("Stuck?");
									//check if nums are the same, then call combine
									//do not call combine or move in here, or it'll loop. Need to break out of here.
									if(tiles.get(z).getNum() == tiles.get(i).getNum())
									{
										combineTiles(tiles.get(i), tiles.get(z), direction);
									}
									moveTile = false;
								}
							}
							if(moveTile == true)
							{
							
								while(moveTile == true)
								{
									
									
									for(int l = 0; l < tiles.size(); l++)
									{
										if(tiles.get(l).getLocation().equals(loc))
										{
											
											moveTile = false;
										}
									}
									if(loc.getCol() < 0 || loc.getCol() > 3)
									{
										System.out.println(tiles.get(i).getLocation().getCol());
										moveTile = false;
									}
									if (moveTile == true)
									{
										tiles.get(i).setLocation(loc);
										loc = tiles.get(i).getLocation().getAdjacentLocation(direction);
										
										
									}
								}
							}
						}
					}
				
				break;
			}
			case"left":
			{
				
				//SORT THE MOTHERTRUCKING ARRAYLIST
				for(int i = 1; i < tiles.size(); i++)
				{
					Tile tempTile = tiles.get(i);
					
					int j;
					for(j = i - 1; j >= 0 && tempTile.getX() < tiles.get(j).getX(); j--)
					{
						tiles.set(j + 1, tiles.get(j));
					}
					
					tiles.set(j + 1, tempTile);
				}
				
				//check if can move, and if it can move, check if it can combine
				for(int i = 0; i < tiles.size(); i++)
				{
					boolean moveTile = true;
	
					//check if location is in valid part of grid
				
						//check if location above is valid part of grid
						if(tiles.get(i).getLocation().getAdjacentLocation(direction).getRow() < 4 && tiles.get(i).getLocation().getAdjacentLocation(direction).getRow() >= 0)
						{
							Location loc = tiles.get(i).getLocation().getAdjacentLocation(direction);
							//find the tile at the loc. If there is none, move the tile to that location
							for(int z = 0; z < tiles.size(); z++)
							{
								if(tiles.get(z).getLocation().equals(loc) == true)
								{
									//System.out.println("Stuck?");
									//check if nums are the same, then call combine
									//do not call combine or move in here, or it'll loop. Need to break out of here.
									if(tiles.get(z).getNum() == tiles.get(i).getNum())
									{
										combineTiles(tiles.get(i), tiles.get(z), direction);
									}
									moveTile = false;
								}
							}
							if(moveTile == true)
							{
								while(moveTile == true)
								{
									
									for(int l = 0; l < tiles.size(); l++)
									{
										if(tiles.get(l).getLocation().equals(loc))
										{
											moveTile = false;
										}
									}
									if(loc.getRow() < 0 || loc.getRow() > 3)
									{
										moveTile = false;
									}
									if (moveTile == true)
									{
										tiles.get(i).setLocation(loc);
										loc = tiles.get(i).getLocation().getAdjacentLocation(direction);
									}
								}
							}
						}
					}
				
				break;
			}
			case"right":
			{
				
				//SORT THE MOTHERTRUCKING ARRAYLIST
				for(int i = 1; i < tiles.size(); i++)
				{
					Tile tempTile = tiles.get(i);
					
					int j;
					for(j = i - 1; j >= 0 && tempTile.getX() > tiles.get(j).getX(); j--)
					{
						tiles.set(j + 1, tiles.get(j));
					}
					
					tiles.set(j + 1, tempTile);
				}
				
				//check if can move, and if it can move, check if it can combine
				for(int i = 0; i < tiles.size(); i++)
				{
					boolean moveTile = true;
	
					//check if location is in valid part of grid
					//check if location above is valid part of grid
						if(tiles.get(i).getLocation().getAdjacentLocation(direction).getRow() < 4 && tiles.get(i).getLocation().getAdjacentLocation(direction).getRow() >= 0)
						{
							Location loc = tiles.get(i).getLocation().getAdjacentLocation(direction);
							//find the tile at the loc. If there is none, move the tile to that location
							for(int z = 0; z < tiles.size(); z++)
							{
								if(tiles.get(z).getLocation().equals(loc) == true)
								{
									//System.out.println("Stuck?");
									//check if nums are the same, then call combine
									//do not call combine or move in here, or it'll loop. Need to break out of here.
									if(tiles.get(z).getNum() == tiles.get(i).getNum())
									{
										combineTiles(tiles.get(i), tiles.get(z), direction);
									}
									moveTile = false;
								}
							}
							if(moveTile == true)
							{
								while(moveTile == true)
								{
									
									for(int l = 0; l < tiles.size(); l++)
									{
										if(tiles.get(l).getLocation().equals(loc))
										{
											moveTile = false;
										}
									}
									if(loc.getRow() < 0 || loc.getRow() > 3)
									{
										moveTile = false;
									}
									if (moveTile == true)
									{
										tiles.get(i).setLocation(loc);
										loc = tiles.get(i).getLocation().getAdjacentLocation(direction);
									}
								}
							}
						}
					}
				
				break;
			}
		}
		generatorMethod();
	}
	
	public static void generatorMethod()
	{
		int numberToSend;
		Color colorToSend;
		openCords = cords;
		boolean remove = false;
		for(Tile theTile : tiles)
		{
			Point thePoint = new Point(theTile.getX(), theTile.getY());
			
			
			for (int i = 0; i < openCords.size(); i++)
			{
				Point points = openCords.get(i);
				if(points.equals(thePoint) && remove == false)
				{
					openCords.remove(points);
					i--;
					remove = true;
				}
				
			}
		}
		if(checker == true)
		{
			object.lost();
			JOptionPane.showMessageDialog(object.label, "YOU DUN GOOFED TODAY SON.");
		}
		if(openCords.size() == 0)
		{
			checker = true;
		}
		else
		{
			checker = false;
			int rand = (int) (Math.random() * openCords.size());
			int xCoord = openCords.get(rand).x;
			int yCoord = openCords.get(rand).y;
			
			
			
			int rand2 = (int) (Math.random() * 10);
			if (rand2 == 9)
			{
				numberToSend = 4;
				colorToSend = new Color(255, 153, 204);
			}
			else
			{
				numberToSend = 2;
				colorToSend = new Color(255, 228, 196);
			}
			
			Tile addedTile = new Tile(colorToSend, numberToSend, xCoord, yCoord, object);
			tiles.add(addedTile);
			
		}
	}
	

	
	public static void combineTiles(Tile tile1, Tile tile2, String direction)
	{
				
				int xloc = 0;
				int yloc = 0;
				if (direction == "up")
				{
					if (tile1.getY() > tile2.getY())
						yloc = tile2.getY();
					else
						yloc = tile1.getY();
					xloc = tile1.getX();
				}
				if (direction == "right")
				{
					if (tile1.getX() > tile2.getX())
						xloc = tile1.getX();
					else
						xloc = tile2.getX();
					yloc = tile2.getY();
				}
				if (direction == "down")
				{
					if (tile1.getY() > tile2.getY())
						yloc = tile1.getY();
					else
						yloc = tile2.getY();
					xloc = tile1.getX();
				}
				if (direction == "left")
				{
					if (tile1.getX() > tile2.getX())
						xloc = tile2.getX();
					else
						xloc = tile1.getX();
					yloc = tile2.getY();
				}
				
				Color color = new Color(0,0,0);
				int nextNum = tile1.getNum() * 2;

				if(nextNum == 4)
					color = new Color(255, 153, 204);
				else if(nextNum == 8)
					color = color.ORANGE;
				else if(nextNum == 16)
				{
					color = color.ORANGE;
					color = color.darker();
				}
				else if(nextNum == 32)
					color = color.CYAN;
				else if(nextNum == 64)
				{
					color = color.CYAN;
					color = color.darker();
				}
				else if(nextNum == 128)
				{
					color = color.YELLOW;
				}
				else if(nextNum == 256)
				{
					color = color.YELLOW;
					color = color.darker();
				}
				else if(nextNum == 512)
				{
					color = color.MAGENTA;
				}
				else if(nextNum == 1024)
				{
					color = color.MAGENTA;
					color = color.darker();
				}
				else if(nextNum == 2048)
				{
					color = color.GREEN;
				}
				else if(nextNum == 4096)
				{
					color = color.GREEN;
					color = color.darker();
				}
				else if(nextNum == 8192)
				{
					color = color.BLUE;
				}
				else
					color = color.darker();
				tile1.removeTile();
				tile2.removeTile();
				object.repaint();
				Tile tile3 = new Tile(color, nextNum, xloc, yloc, object);
				tiles.add(tile3);
			
				lol:
				for(int x = 0; x < tiles.size(); x ++)
				{
					if(tiles.get(x).getX() == tile1.getX() && tiles.get(x).getY() == tile1.getY())
					{
						tiles.remove(x);
						break lol;
					}
				}
				
				
				sus:
					for(int x = 0; x < tiles.size(); x ++)
					{
						if(tiles.get(x).getX() == tile2.getX() && tiles.get(x).getY() == tile2.getY())
						{
							tiles.remove(x);
							break sus;
						}
					}
			
				
				countMethod(tile3);
					
				
				
				 //Alternate way to change tile color (doesn't work)
				/* 
				Color colorC = tile1.getColor();
				int red = colorC.getRed();
				int green = colorC.getGreen();
				int blue = colorC.getBlue();
				if (decrease == true)
				{
					if (red > 10)
						red -= 10;
					else if (green > 10)
						green -=10;
					else if (blue > 10)
						blue -=10;
					else
						decrease = false;
				}
				else
				{
					if (red < 235)
						red += 20;
					else if (green < 235)
						green +=20;
					else if (blue<235)
						blue -=10;
					else
						decrease = true;
				}		
				
					
				
				
				tile1.removeTile();
				tile2.removeTile();
				object.repaint();
				Tile tile4 = new Tile(new Color(red, green, blue), nextNum, xloc, yloc, object);
				tiles.add(tile4);
				countMethod(tile4);
				*/
				
		//Add tiles together depending on which way it is sliding
	}
	
	public static void getObject(GameScreen obj)
	{
		object = obj;
	}


}
